package cn.walls1717.wallsmall.product.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.walls1717.wallsmall.common.utils.PageUtils;
import cn.walls1717.wallsmall.common.utils.Query;
import cn.walls1717.wallsmall.common.utils.R;
import cn.walls1717.wallsmall.product.dao.SkuInfoDao;
import cn.walls1717.wallsmall.product.entity.SkuImagesEntity;
import cn.walls1717.wallsmall.product.entity.SkuInfoEntity;
import cn.walls1717.wallsmall.product.entity.SpuInfoDescEntity;
import cn.walls1717.wallsmall.product.feign.SeckillFeignService;
import cn.walls1717.wallsmall.product.service.*;
import cn.walls1717.wallsmall.product.vo.SeckillInfoVO;
import cn.walls1717.wallsmall.product.vo.SkuItemSaleAttrVO;
import cn.walls1717.wallsmall.product.vo.SkuItemVO;
import cn.walls1717.wallsmall.product.vo.SpuItemAttrGroupVO;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

@Service("skuInfoService")
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoDao, SkuInfoEntity> implements SkuInfoService {
    @Resource
    private SkuImagesService skuImagesService;
    @Resource
    private SpuInfoDescService spuInfoDescService;
    @Resource
    private AttrGroupService attrGroupService;
    @Resource
    private SkuSaleAttrValueService skuSaleAttrValueService;
    @Resource
    private ThreadPoolExecutor executor;
    @Resource
    private SeckillFeignService seckillFeignService;

    /**
     * 条件分页查询
     *
     * @param params 查询参数
     * @return 分页数据
     */
    @Override
    public PageUtils listPagesByConditions(Map<String, Object> params) {
        LambdaQueryWrapper<SkuInfoEntity> lqw = new LambdaQueryWrapper<>();
        // 查询条件id、name
        String key = (String)params.get("key");
        if (!StrUtil.isEmpty(key)) {
            lqw.and(w -> w.eq(SkuInfoEntity::getSkuId, key)).or().like(SkuInfoEntity::getSkuName, key);
        }
        // 查询条件catelogId
        String catalogId = (String)params.get("catelogId");
        if (!StrUtil.isEmpty(catalogId) && !StrUtil.equals(catalogId, "0")) {
            lqw.eq(SkuInfoEntity::getCatalogId, catalogId);
        }
        // 查询条件brandId
        String brandId = (String)params.get("brandId");
        if (!StrUtil.isEmpty(brandId) && !StrUtil.equals(brandId, "0")) {
            lqw.eq(SkuInfoEntity::getBrandId, brandId);
        }
        // 查询条件price
        String min = (String)params.get("min");
        if (!StrUtil.isEmpty(min)) {
            lqw.ge(SkuInfoEntity::getPrice, min);
        }
        String max = (String)params.get("max");
        if (!StrUtil.isEmpty(max)) {
            BigDecimal maxPrice = new BigDecimal(max);
            if (maxPrice.compareTo(new BigDecimal("0")) > 0) {
                lqw.le(SkuInfoEntity::getPrice, max);
            }
        }

        IPage<SkuInfoEntity> page = this.page(new Query<SkuInfoEntity>().getPage(params), lqw);
        return new PageUtils(page);
    }

    /**
     * 根据spuId查找sku信息
     *
     * @param spuId spuId
     * @return sku信息集合
     */
    @Override
    public List<SkuInfoEntity> listSkusBySpuId(Long spuId) {
        return lambdaQuery().eq(SkuInfoEntity::getSpuId, spuId).list();
    }

    /**
     * 根据skuId获取商品的前台展示数据
     *
     * @param skuId skuId
     * @return 前台展示数据
     */
    @Override
    public SkuItemVO getItemBySkuId(Long skuId) {
        SkuItemVO skuItemVO = new SkuItemVO();
        // 获取sku的详情
        CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
            SkuInfoEntity skuInfo = getById(skuId);
            skuItemVO.setInfo(skuInfo);
            return skuInfo;
        }, executor);
        // 获取spu图片描述
        CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync((res) -> {
            SpuInfoDescEntity spuInfoDesc = spuInfoDescService.getById(res.getSpuId());
            skuItemVO.setDesc(spuInfoDesc);
        }, executor);
        // 获取sku销售属性
        CompletableFuture<Void> saleAttrFuture = infoFuture.thenAcceptAsync((res) -> {
            List<SkuItemSaleAttrVO> skuSaleAttrs = skuSaleAttrValueService.listSaleAttrsBySpuId(res.getSpuId());
            skuItemVO.setSaleAttr(skuSaleAttrs);
        }, executor);
        // 获取sku基本属性
        CompletableFuture<Void> attrGroupFuture = infoFuture.thenAcceptAsync((res) -> {
            List<SpuItemAttrGroupVO> attrGroups =
                    attrGroupService.listAttrGroupsWithAttrsBySpuIdCatalogId(res.getSpuId(), res.getCatalogId());
            skuItemVO.setGroupAttrs(attrGroups);
        }, executor);
        // 获取sku图片
        CompletableFuture<Void> imgFuture = CompletableFuture.runAsync(() -> {
            List<SkuImagesEntity> skuImages = skuImagesService.listSkuImagesBySkuId(skuId);
            skuItemVO.setImages(skuImages);
        }, executor);
        // 获取秒杀优惠信息
        CompletableFuture<Void> seckillFuture = CompletableFuture.runAsync(() -> {
            R r = seckillFeignService.getSkuSeckillInfoBySkuId(skuId);
            if (r.getCode()==0) {
                SeckillInfoVO seckillInfoVO = r.getData("data", new TypeReference<SeckillInfoVO>(){});
                skuItemVO.setSeckillInfo(seckillInfoVO);
            }
        }, executor);


        // 等待所有线程完成
        try {
            CompletableFuture.allOf(descFuture, saleAttrFuture, attrGroupFuture, imgFuture, seckillFuture).get();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return skuItemVO;
    }
}